package cn.huiyunche.base.service.interfaces.impl;

import cn.huiyunche.base.service.interfaces.JPushService;
import cn.huiyunche.base.service.interfaces.PushService;
import cn.huiyunche.base.service.interfaces.UserDeviceService;
import cn.huiyunche.base.service.model.SUserDevices;
import cn.jpush.api.JPushClient;
import cn.jpush.api.common.ClientConfig;
import cn.jpush.api.common.resp.APIConnectionException;
import cn.jpush.api.common.resp.APIRequestException;
import cn.jpush.api.push.PushResult;
import cn.jpush.api.push.model.Message;
import cn.jpush.api.push.model.Options;
import cn.jpush.api.push.model.Platform;
import cn.jpush.api.push.model.PushPayload;
import cn.jpush.api.push.model.audience.Audience;
import cn.jpush.api.push.model.audience.AudienceTarget;
import cn.jpush.api.push.model.notification.AndroidNotification;
import cn.jpush.api.push.model.notification.IosAlert;
import cn.jpush.api.push.model.notification.IosNotification;
import cn.jpush.api.push.model.notification.Notification;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;

@Service
public class PushServiceImpl implements PushService {

    private static final Logger LOGGER = LoggerFactory.getLogger(PushServiceImpl.class);

    @Value("${jpush.appKey.driver}")
    private String appKey;
    @Value("${jpush.masterSecret.driver}")
    private String masterSecret;


    @Autowired
    private UserDeviceService userDeviceService;

    @Autowired
    private JPushService jPushService;

    //	@Async
    public void notifyKyleUser(Long userid, String msg) {
        if (null == userid || StringUtils.isEmpty(msg)) {
            return;
        }
        SUserDevices userDevice = userDeviceService.getUserLastDevice(userid);
        if (null == userDevice || null == userDevice.getPushid()) {
            return;
        }
        String pushid = userDevice.getPushid();
        List<String> ids = new ArrayList<String>();
        ids.add(pushid);
        jPushService.sendMsgKyle(ids, msg);
    }

    @Override
    public PushResult pushObjectAllAllAlert(String alert) {
        JPushClient jpushClient = new JPushClient(masterSecret, appKey, 3);
        // For push, all you need do is to build PushPayload object.
        PushPayload payload = PushPayload.alertAll(alert);
        PushResult result = null;
        try {
            result = jpushClient.sendPush(payload);
            LOGGER.info("Got result - " + result);
        } catch (APIConnectionException e) {
            LOGGER.error("Connection error. Should retry later. ", e);

        } catch (APIRequestException e) {
            LOGGER.error("Error response from JPush server. Should review and fix it. ", e);
            LOGGER.info("HTTP Status: " + e.getStatus());
            LOGGER.info("Error Code: " + e.getErrorCode());
            LOGGER.info("Error Message: " + e.getErrorMessage());
            LOGGER.info("Msg ID: " + e.getMsgId());
        }
        return result;
    }

    @Override
    public PushResult buildPushObjectAllAliasAlert(String alert, String... alias) {
        JPushClient jpushClient = new JPushClient(masterSecret, appKey, 3);
        // For push, all you need do is to build PushPayload object.
        PushPayload payload = PushPayload.newBuilder()
                .setPlatform(Platform.all())
                .setAudience(Audience.alias(alias))
                .setNotification(Notification.alert(alert))
                .build();
        PushResult result = null;
        try {
            result = jpushClient.sendPush(payload);
            LOGGER.info("Got result - " + result);
        } catch (APIConnectionException e) {
            LOGGER.error("Connection error. Should retry later. ", e);
        } catch (APIRequestException e) {
            LOGGER.error("Error response from JPush server. Should review and fix it. ", e);
            LOGGER.info("HTTP Status: " + e.getStatus());
            LOGGER.info("Error Code: " + e.getErrorCode());
            LOGGER.info("Error Message: " + e.getErrorMessage());
            LOGGER.info("Msg ID: " + e.getMsgId());
        }
        return result;
    }

    @Override
    public PushResult buildPushObjectAndroidTagAlertWithTitle(String alert, String title, String... tagValue) {
        JPushClient jpushClient = new JPushClient(masterSecret, appKey, 3);
        // For push, all you need do is to build PushPayload object.
        PushPayload payload = PushPayload.newBuilder()
                .setPlatform(Platform.android())
                .setAudience(Audience.tag(tagValue))
                .setNotification(Notification.android(alert, title, null))
                .build();
        PushResult result = null;
        try {
            result = jpushClient.sendPush(payload);
            LOGGER.info("Got result - " + result);
        } catch (APIConnectionException e) {
            LOGGER.error("Connection error. Should retry later. ", e);

        } catch (APIRequestException e) {
            LOGGER.error("Error response from JPush server. Should review and fix it. ", e);
            LOGGER.info("HTTP Status: " + e.getStatus());
            LOGGER.info("Error Code: " + e.getErrorCode());
            LOGGER.info("Error Message: " + e.getErrorMessage());
            LOGGER.info("Msg ID: " + e.getMsgId());
        }
        return result;
    }

    @Override
    public PushResult buildPushObjectAndroidAndIos(String alertContent, String androidTitle,
                                                   String extraKey, String extraValue, String... tagValue) {
        JPushClient jpushClient = new JPushClient(masterSecret, appKey, 3);
        // For push, all you need do is to build PushPayload object.
        PushPayload payload = PushPayload.newBuilder()
                .setPlatform(Platform.android_ios())
                .setAudience(Audience.tag(tagValue))
                .setNotification(Notification.newBuilder()
                        .setAlert(alertContent)
                        .addPlatformNotification(AndroidNotification.newBuilder()
                                .setTitle(androidTitle).build())
                        .addPlatformNotification(IosNotification.newBuilder()
                                .incrBadge(1)
                                .addExtra(extraKey, extraValue).build())
                        .build())
                .build();
        PushResult result = null;
        try {
            result = jpushClient.sendPush(payload);
            LOGGER.info("Got result - " + result);
        } catch (APIConnectionException e) {
            LOGGER.error("Connection error. Should retry later. ", e);

        } catch (APIRequestException e) {
            LOGGER.error("Error response from JPush server. Should review and fix it. ", e);
            LOGGER.info("HTTP Status: " + e.getStatus());
            LOGGER.info("Error Code: " + e.getErrorCode());
            LOGGER.info("Error Message: " + e.getErrorMessage());
            LOGGER.info("Msg ID: " + e.getMsgId());
        }
        return result;
    }

    @Override
    public PushResult buildPushObjectIosTagAndAlertWithExtrasAndMessage(String alert,
                                                                        String sound, String extraKey, String extraValue, String msgContent, String... tagValue) {
        JPushClient jpushClient = new JPushClient(masterSecret, appKey, 3);
        // For push, all you need do is to build PushPayload object.
        PushPayload payload = PushPayload.newBuilder()
                .setPlatform(Platform.ios())
                .setAudience(Audience.tag_and(tagValue))
                .setNotification(Notification.newBuilder()
                        .addPlatformNotification(IosNotification.newBuilder()
                                .setAlert(alert)
                                .setBadge(5)
                                .setSound(sound)
                                .addExtra(extraKey, extraValue)
                                .build())
                        .build())
                .setMessage(Message.content(msgContent))
                .setOptions(Options.newBuilder()
                        .setApnsProduction(true)
                        .build())
                .build();
        PushResult result = null;
        try {
            result = jpushClient.sendPush(payload);
            LOGGER.info("Got result - " + result);
        } catch (APIConnectionException e) {
            LOGGER.error("Connection error. Should retry later. ", e);

        } catch (APIRequestException e) {
            LOGGER.error("Error response from JPush server. Should review and fix it. ", e);
            LOGGER.info("HTTP Status: " + e.getStatus());
            LOGGER.info("Error Code: " + e.getErrorCode());
            LOGGER.info("Error Message: " + e.getErrorMessage());
            LOGGER.info("Msg ID: " + e.getMsgId());
        }
        return result;
    }

    @Override
    public PushResult buildPushObjectIosAudienceMoreMessageWithExtras(Collection<String> tags, Collection<String> alias, String msgContent) {
        JPushClient jpushClient = new JPushClient(masterSecret, appKey, 3);
        // For push, all you need do is to build PushPayload object.
        PushPayload payload = PushPayload.newBuilder()
                .setPlatform(Platform.android_ios())
                .setAudience(Audience.newBuilder()
                        .addAudienceTarget(AudienceTarget.tag(tags))
                        .addAudienceTarget(AudienceTarget.alias(alias))
                        .build())
                .setMessage(Message.newBuilder()
                        .setMsgContent(msgContent)
                        .addExtra("from", "JPush")
                        .build())
                .build();
        PushResult result = null;
        try {
            result = jpushClient.sendPush(payload);
            LOGGER.info("Got result - " + result);
        } catch (APIConnectionException e) {
            LOGGER.error("Connection error. Should retry later. ", e);

        } catch (APIRequestException e) {
            LOGGER.error("Error response from JPush server. Should review and fix it. ", e);
            LOGGER.info("HTTP Status: " + e.getStatus());
            LOGGER.info("Error Code: " + e.getErrorCode());
            LOGGER.info("Error Message: " + e.getErrorMessage());
            LOGGER.info("Msg ID: " + e.getMsgId());
        }
        return result;
    }

    @Override
    public PushResult sendPushWithCustomConfig(String hostName, String alert) {
        ClientConfig config = ClientConfig.getInstance();
        // Setup the custom hostname
        config.setPushHostName(hostName);

        JPushClient jpushClient = new JPushClient(masterSecret, appKey, 3, null, config);

        // For push, all you need do is to build PushPayload object.
        PushPayload payload = PushPayload.alertAll(alert);
        PushResult result = null;
        try {
            result = jpushClient.sendPush(payload);
            LOGGER.info("Got result - " + result);

        } catch (APIConnectionException e) {
            LOGGER.error("Connection error. Should retry later. ", e);

        } catch (APIRequestException e) {
            LOGGER.error("Error response from JPush server. Should review and fix it. ", e);
            LOGGER.info("HTTP Status: " + e.getStatus());
            LOGGER.info("Error Code: " + e.getErrorCode());
            LOGGER.info("Error Message: " + e.getErrorMessage());
            LOGGER.info("Msg ID: " + e.getMsgId());
        }
        return result;
    }

    @Override
    public PushResult sendIosAlert(String title, String body, String actionLocKey) {
        JPushClient jpushClient = new JPushClient(masterSecret, appKey);

        IosAlert alert = IosAlert.newBuilder()
                .setTitleAndBody(title, body)
                .setActionLocKey(actionLocKey)
                .build();
        PushResult result = null;
        try {
            result = jpushClient.sendIosNotificationWithAlias(alert, new HashMap<String, String>(), "alias1");
            LOGGER.info("Got result - " + result);
        } catch (APIConnectionException e) {
            LOGGER.error("Connection error. Should retry later. ", e);
        } catch (APIRequestException e) {
            LOGGER.error("Error response from JPush server. Should review and fix it. ", e);
            LOGGER.info("HTTP Status: " + e.getStatus());
            LOGGER.info("Error Code: " + e.getErrorCode());
            LOGGER.info("Error Message: " + e.getErrorMessage());
        }
        return result;
    }

    @Override
    public PushResult sendAndroidAlert(String title, String body, String actionLockey) {

        return null;
    }


}
